﻿using System.Collections.Generic;

namespace ZquenceStudio3Host.DspPlugins.Synthesizers.Nodesizer.Engine.Modules.Converters
{
    [ModuleDisplay("Midi Voice 4")]
    public class Voice4Module : BaseModule
    {
        private MidiMessageHandler mMidiHandler = new MidiMessageHandler();
#if DEBUG
        private Dictionary<int, int> mCurrentNotes = new Dictionary<int, int>();
        private Dictionary<int, int> mCurrentNotes2 = new Dictionary<int, int>(); // Total played notes.
#endif

        public readonly ModuleInput MidiIn;
        public readonly ModuleOutput[] MidiNoteOuts;

        public Voice4Module(ModuleManager manager)
            : base(manager)
        {
            AddInput(MidiIn = new ModuleInput("In", IOType.Midi, this));
            MidiNoteOuts = new ModuleOutput[4];
            for (int i = 0; i < MidiNoteOuts.Length; i++)
            {
                MidiNoteOuts[i] = new ModuleOutput("Out" + (i + 1), IOType.Midi, this);
                AddOutput(MidiNoteOuts[i]);
            }
        }

        public override void Process()
        {
            if (MidiIn.IsConnected)
            {
                var keyVoiceMap = mMidiHandler.ProcessMidi(MidiIn.FromOutput.MidiBuffer);

#if DEBUG
                foreach (var item in keyVoiceMap)
                {
                    foreach (var midi in item.Value)
                    {
                        if (midi.Message.MidiData.Status == SoundEngine3.MIDI.Meta.MidiStatus.NOTE_ON)
                        {
                            if (!mCurrentNotes.ContainsKey(midi.Message.MidiData.Parameter1))
                            {
                                mCurrentNotes.Add(midi.Message.MidiData.Parameter1, 0);
                            }
                            mCurrentNotes[midi.Message.MidiData.Parameter1]++;

                            // Total played notes.
                            int voiceIndex = item.Key;
                            if (voiceIndex != midi.VoiceIndex)
                            {

                            }
                            if (!mCurrentNotes2.ContainsKey(voiceIndex))
                            {
                                mCurrentNotes2.Add(voiceIndex, 0);
                            }
                            mCurrentNotes2[voiceIndex]++;
                        }
                        else if (midi.Message.MidiData.Status == SoundEngine3.MIDI.Meta.MidiStatus.NOTE_OFF)
                        {
                            if (mCurrentNotes.ContainsKey(midi.Message.MidiData.Parameter1))
                            {
                                mCurrentNotes[midi.Message.MidiData.Parameter1]--;

                                if (mCurrentNotes[midi.Message.MidiData.Parameter1] == 0)
                                {
                                    mCurrentNotes.Remove(midi.Message.MidiData.Parameter1);
                                }
                            }
                        }
                    }
                }

#endif

                if (keyVoiceMap.Count > 0)
                {
                    foreach (var message in keyVoiceMap)
                    {
                        int noteId = message.Key;
                        
                        // Note voices above limit will use the last allowed note.
                        if (noteId >= MidiNoteOuts.Length)
                        {
                            noteId = MidiNoteOuts.Length - 1; // TODO: Trycker ner 2 tangenter, första drar jag upp, klickar på ny, men hamnar på index 2 igen :O
                        }

                        foreach (var midi in message.Value)
                        {
                            MidiNoteOuts[noteId].AddMidiMessage(midi.Message);
                        }
                    }
                }
            }
        }
    }
}
